From c2c96a6591d00fd2df21359fb00a328446ee1c50 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Wed, 2 Jul 2014 16:32:24 -0700 Subject: [PATCH] Add support for non-transitive dependencies Development and test dependencies should not be transitively pulled in. For example, if I use rust-curl, and it happens to use hamcrest for testing, that does not mean I depend on hamcrest. --- src/cargo/core/dependency.rs | 16 +++++++++++-- src/cargo/core/resolver.rs | 45 +++++++++++++++++++++++++++++------- 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/src/cargo/core/dependency.rs b/src/cargo/core/dependency.rs index 6e4c8b25f..a96e89561 100644 --- a/src/cargo/core/dependency.rs +++ b/src/cargo/core/dependency.rs @@ -5,7 +5,8 @@ use util::CargoResult; pub struct Dependency { name: String, namespace: SourceId, - req: VersionReq + req: VersionReq, + transitive: bool } impl Dependency { @@ -20,7 +21,8 @@ impl Dependency { Ok(Dependency { name: name.to_str(), namespace: namespace.clone(), - req: version + req: version, + transitive: true }) } @@ -35,6 +37,16 @@ impl Dependency { pub fn get_namespace<'a>(&'a self) -> &'a SourceId { &self.namespace } + + pub fn as_dev(&self) -> Dependency { + let mut dep = self.clone(); + dep.transitive = false; + dep + } + + pub fn is_transitive(&self) -> bool { + self.transitive + } } #[deriving(PartialEq,Clone,Encodable)] diff --git a/src/cargo/core/resolver.rs b/src/cargo/core/resolver.rs index 2f07aaf74..ee51c9680 100644 --- a/src/cargo/core/resolver.rs +++ b/src/cargo/core/resolver.rs @@ -47,6 +47,8 @@ pub fn resolve(deps: &[Dependency], resolve.insert(pkg.get_name().to_str(), pkg.clone()); for dep in pkg.get_dependencies().iter() { + if !dep.is_transitive() { continue; } + if !resolve.contains_key_equiv(&dep.get_name()) { remaining.push(dep.clone()); } @@ -63,18 +65,31 @@ mod test { use core::{Dependency, PackageId, Summary}; use super::resolve; - macro_rules! pkg( - ($name:expr => $($deps:expr),+) => ( - { + trait ToDep { + fn to_dep(self) -> Dependency; + } + + impl ToDep for &'static str { + fn to_dep(self) -> Dependency { let url = url::from_str("http://example.com").unwrap(); let source_id = SourceId::new(RegistryKind, Remote(url)); - let d: Vec = vec!($($deps),+).iter().map(|s| { - Dependency::parse(*s, Some("1.0.0"), &source_id).unwrap() - }).collect(); + Dependency::parse(self, Some("1.0.0"), &source_id).unwrap() + } + } + + impl ToDep for Dependency { + fn to_dep(self) -> Dependency { + self + } + } + + macro_rules! pkg( + ($name:expr => $($deps:expr),+) => ({ + let d: Vec = vec!($($deps.to_dep()),+); + Summary::new(&PackageId::new($name, "1.0.0", ®istry_loc()).unwrap(), d.as_slice()) - } - ); + }); ($name:expr) => ( Summary::new(&PackageId::new($name, "1.0.0", ®istry_loc()).unwrap(), @@ -153,4 +168,18 @@ mod test { assert_that(&res, contains(names(["foo", "bar"]))); } + + #[test] + pub fn test_resolving_with_dev_deps() { + let mut reg = registry(vec!( + pkg!("foo" => "bar", dep("baz").as_dev()), + pkg!("baz" => "bat", dep("bam").as_dev()), + pkg!("bar"), + pkg!("bat") + )); + + let res = resolve([dep("foo"), dep("baz").as_dev()], &mut reg).unwrap(); + + assert_that(&res, contains(names(["foo", "bar", "baz"]))); + } } -- 2.30.2